package com.athuahua.spzx.service.impl;

import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson2.JSON;
import com.athuahua.spzx.entity.ProductSku;
import com.athuahua.spzx.feignapi.ProductFeignClient;
import com.athuahua.spzx.vo.CartInfoVo;
import com.athuahua.spzx.service.CartService;
import com.athuahua.spzx.utils.BaseContext;
import com.athuahua.spzx.vo.ProductSkuVo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: huahua
 * @Date: 2024/8/16 0016
 * @Time: 2:31
 * @Description:
 */
@Service
@Slf4j
public class CartServiceImpl implements CartService {
    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Resource
    private ProductFeignClient productFeignClient;

    private String getCartKey(Long currentId) {
        return "user:cart:" + currentId;
    }

    /**
     * Redis hash类型
     * key: 用户id
     * field: 商品skuId
     * value: sku信息
     */
    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        //获取当前用户id
        Long currentId = BaseContext.getCurrentId();
        //获取购物车key
        String cartKey = getCartKey(currentId);
        //从购物车取出数据
        Object cartInfoObj = redisTemplate.opsForHash().get(cartKey, String.valueOf(skuId));
        CartInfoVo cartInfoVo = null;
        if (cartInfoObj != null) {
            //购物车中已有该商品，更新数量
            cartInfoVo = JSON.parseObject(cartInfoObj.toString(), CartInfoVo.class);
            cartInfoVo.setSkuNum(cartInfoVo.getSkuNum() + skuNum);
            cartInfoVo.setIsChecked(1);
            cartInfoVo.setUpdateTime(DateTime.now());
        } else {
            //购物车中没有该商品，新增商品
            cartInfoVo = new CartInfoVo();
            //TODO:通过openFeign远程获取商品sku信息
            ProductSku productSku = productFeignClient.getBySkuId(skuId);
            cartInfoVo.setCartPrice(productSku.getSalePrice());
            cartInfoVo.setSkuNum(skuNum);
            cartInfoVo.setSkuId(skuId);
            cartInfoVo.setUserId(currentId);
            cartInfoVo.setImgUrl(productSku.getThumbImg());
            cartInfoVo.setSkuName(productSku.getSkuName());
            cartInfoVo.setIsChecked(1);
            cartInfoVo.setUpdateTime(DateTime.now());
            cartInfoVo.setCreateTime(DateTime.now());

        }

        redisTemplate.opsForHash().put(
                cartKey, String.valueOf(skuId), JSON.toJSONString(cartInfoVo));

    }

    @Override
    public List<CartInfoVo> getCartList() {
        //获取当前用户id
        Long currentId = BaseContext.getCurrentId();
        //获取购物车key
        String cartKey = getCartKey(currentId);
        //从购物车取出数据
        List<Object> valueList = redisTemplate.opsForHash().values(cartKey);
        if (!CollectionUtils.isEmpty(valueList)) {
            return valueList.stream().map(cartInfoObj ->
                            JSON.parseObject(cartInfoObj.toString(), CartInfoVo.class))
                    .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime())) //排序
                    .toList();
        }
        return new ArrayList<>();
    }

    @Override
    public void deleteCart(Long skuId) {
        //获取当前用户id
        Long currentId = BaseContext.getCurrentId();
        //获取购物车key
        String cartKey = getCartKey(currentId);

        redisTemplate.opsForHash().delete(cartKey, String.valueOf(skuId));
    }

    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        //获取当前用户id
        Long currentId = BaseContext.getCurrentId();
        //获取购物车key
        String cartKey = getCartKey(currentId);

        Boolean b = redisTemplate.opsForHash().hasKey(cartKey, String.valueOf(skuId));
        if (b) {
            CartInfoVo cartInfoVo = JSON.parseObject(redisTemplate.opsForHash().get(cartKey, String.valueOf(skuId)).toString(), CartInfoVo.class);
            cartInfoVo.setIsChecked(isChecked);
            redisTemplate.opsForHash().put(cartKey, String.valueOf(skuId), JSON.toJSONString(cartInfoVo));
        }
    }

    @Override
    public void AllCheckCart(Integer isChecked) {
        //获取当前用户id
        Long currentId = BaseContext.getCurrentId();
        //获取购物车key
        String cartKey = getCartKey(currentId);

        List<Object> valueList = redisTemplate.opsForHash().values(cartKey);
        if (!CollectionUtils.isEmpty(valueList)) {
            valueList.stream().map(cartInfoObj -> JSON.parseObject(cartInfoObj.toString(), CartInfoVo.class))
                    .forEach(cartInfoVo -> {
                        cartInfoVo.setIsChecked(isChecked);
                        redisTemplate.opsForHash().put(cartKey, String.valueOf(cartInfoVo.getSkuId()), JSON.toJSONString(cartInfoVo));
                    });
        }

    }

    @Override
    public void clearCart() {
        //获取当前用户id
        Long currentId = BaseContext.getCurrentId();
        //获取购物车key
        String cartKey = getCartKey(currentId);

        redisTemplate.delete(cartKey);
    }

    @Override
    public List<CartInfoVo> getAllCkecked() {
        //获取当前用户id
        Long currentId = BaseContext.getCurrentId();
        //获取购物车key
        String cartKey = getCartKey(currentId);

        List<CartInfoVo> collect = redisTemplate.opsForHash().values(cartKey).stream().map(
                        cartInfoObj -> JSON.parseObject(cartInfoObj.toString(), CartInfoVo.class))
                .filter(cartInfoVo -> cartInfoVo.getIsChecked() == 1)
                .toList();

        return collect;
    }

    @Override
    public void deleteChecked() {
        //获取当前用户id
        Long currentId = BaseContext.getCurrentId();
        //获取购物车key
        String cartKey = getCartKey(currentId);

        List<Object> objectList = redisTemplate.opsForHash().values(cartKey);

        //删除
        objectList.stream()
                .map(object -> JSON.parseObject(object.toString(), CartInfoVo.class))
                .filter(cartInfoVo -> cartInfoVo.getIsChecked() == 1)
                .forEach(cartInfoVo -> redisTemplate.opsForHash().delete(cartKey
                        , String.valueOf(cartInfoVo.getSkuId())));
    }


}
